package cn.fintecher.pangolin.service.manage.aop;

import cn.fintecher.pangolin.common.enums.BaseSelect;
import cn.fintecher.pangolin.common.enums.DeviceType;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.response.LoginResponse;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.SystemLoginLog;
import cn.fintecher.pangolin.service.manage.elastic.SystemLoginLogElastic;
import cn.fintecher.pangolin.service.manage.request.LoginRequest;
import cn.fintecher.pangolin.service.manage.service.BaseService;
import org.apache.catalina.connector.RequestFacade;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;

import java.util.Locale;
import java.util.UUID;

/**
 * @Auther: xiaqun
 * @Description: PC登录日志aop
 * @Date: 17:23 2019/8/19
 */

@Aspect
@Component
public class LoginLogAop {
    @Autowired
    private BaseService baseService;

    @Autowired
    private SystemLoginLogElastic systemLoginLogElastic;

    @Autowired
    private MessageSource messageSource;

    @Pointcut("execution(public * cn.fintecher.pangolin.service.manage.service.UserService.login(..))")
    public void saveLoginLog() {
    }

    @Around("saveLoginLog()")
    public Object doAop(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        SystemLoginLog systemLoginLog = new SystemLoginLog();
        systemLoginLog.setLoginTime(ZWDateUtil.getNowDateTime());
        systemLoginLog.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        try {
            doBefore(proceedingJoinPoint, systemLoginLog);
            Object object = proceedingJoinPoint.proceed();
            doAfter(object, systemLoginLog);
            return object;
        } catch (Throwable throwable) {
            doThrowException(throwable, systemLoginLog);
            throw  throwable;
        }
    }

    /**
     * 登录前执行
     */
    private void doBefore(ProceedingJoinPoint proceedingJoinPoint, SystemLoginLog systemLoginLog) {
        Object[] objects = proceedingJoinPoint.getArgs();
        for (Object object : objects) {
            if (object.getClass().equals(LoginRequest.class)) {
                LoginRequest loginRequest = (LoginRequest) object;
                systemLoginLog.setUsername(loginRequest.getUsername());
                systemLoginLog.setType(DeviceType.PC);
            } else if (object.getClass().equals(RequestFacade.class)) {
                RequestFacade requestFacade = (RequestFacade) object;
                String ip = baseService.getAddressIP(requestFacade);
                systemLoginLog.setIp(ip);
            }
        }
    }

    /**
     * 登录后执行
     */
    private void doAfter(Object result, SystemLoginLog systemLoginLog) {
        if (result.getClass().equals(LoginResponse.class)) {
            LoginResponse response = (LoginResponse) result;
            systemLoginLog.setIsSuccess(BaseSelect.YES);
            systemLoginLog.setRealName(response.getUserModel().getRealName());
            systemLoginLogElastic.save(systemLoginLog);
        }
    }

    /***
     * 捕捉到异常执行
     */
    private void doThrowException(Throwable ex, SystemLoginLog systemLoginLog) {
        if (ex.getClass().equals(BadRequestException.class)) {
            systemLoginLog.setReason(messageSource.getMessage(ex.getMessage(), null, Locale.CHINA));
        } else {
            systemLoginLog.setReason("系统异常");
        }
        systemLoginLog.setIsSuccess(BaseSelect.NO);
        systemLoginLogElastic.save(systemLoginLog);
    }
}
